package com.xhwl.data.service.impl;

import com.xhwl.common.dto.cent.sdata.AccountDetailDTO;
import com.xhwl.common.enums.LogTypeEnum;
import com.xhwl.common.enums.OperationTypeEnum;
import com.xhwl.common.enums.SourceClientEnum;
import com.xhwl.common.es.EsPage;
import com.xhwl.common.exception.ApplicationException;
import com.xhwl.common.exception.DataException;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.query.cent.sdata.ProjectQuery;
import com.xhwl.common.vo.cent.sdata.LoginLogMobileVO;
import com.xhwl.common.vo.cent.sdata.LoginLogPlatformVO;
import com.xhwl.common.vo.cent.sdata.OperateLogVO;
import com.xhwl.data.service.*;
import com.xhwl.data.util.SpringContextUtils;
import com.xhwl.data.util.excel.ExcelExportUtils;
import com.xhwl.starter.log.LogQuery;
import com.xhwl.starter.log.LogTemplate;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;


import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @Author JCccc
 * @Description 2021-08-12 函数抽离
 * @Date 2021/6/29 16:34
 */
@Service
public class LogServiceImpl implements ILogService {
    private static final Logger log = LoggerFactory.getLogger(LogServiceImpl.class);
    @Autowired
    LogTemplate logTemplate;
    @Autowired
    IAccountService accountService;
    @Autowired
    IProjectService projectService;
    @Autowired
    IEnterpriseService enterpriseService;

    @Autowired
    ExcelExportUtils excelExportUtils;

    /**
     * 日志搜索 （操作日志 、 登录日志）
     *
     * @param logQuery
     * @return
     */
    @Override
    public EsPage getPageList(LogQuery logQuery) {
        EsPage esPage = new EsPage();
        if (LogTypeEnum.OPERATE_LOG.getType() == logQuery.getLogType()) {
            return getOperateLog(logQuery);
        } else if (LogTypeEnum.LOGIN_LOG.getType() == logQuery.getLogType()) {
            EsPage loginLogPage = getLoginLog(logQuery);
            List<LoginLog> records = loginLogPage.getRecords();
            for (LoginLog loginLog:records){
                if (StringUtils.isEmpty(loginLog.getEvent())){
                    loginLog.setEvent("loginIn");
                }
            }


            return loginLogPage;
        }
        return esPage;
    }

    /**
     * 新增操作日志
     *
     * @param operateLog
     * @return
     */
    @Override
    public ResultJson addOperateLog(OperateLog operateLog) {
        try {
            if (null != operateLog.getAccountId()) {
                if (StringUtils.isEmpty(operateLog.getLoginName())) {
                    Account account = accountService.findById(operateLog.getAccountId());
                    if (null!=account){
                        operateLog.setLoginName(account.getLoginName());
                        operateLog.setName(account.getName());
                        //填充企业ids+项目ids
                        List<Enterprise> enterprises = enterpriseService.list(null,account);
                        if (!org.springframework.util.CollectionUtils.isEmpty(enterprises)){
                            operateLog.setEnterpriseIds(enterprises.stream().map(Enterprise::getId).collect(Collectors.toList()));
                        }
                        List<AccountDetailDTO> projectInfoList = accountService.getAccountProjectInfoByIdList(Collections.singletonList(account.getId()));
                        operateLog.setProjectIds(projectInfoList.stream().map(AccountDetailDTO::getProjectId).collect(Collectors.toList()));
                        if (!org.springframework.util.CollectionUtils.isEmpty(projectInfoList)){
                            operateLog.setProjectIds(projectInfoList.stream().map(AccountDetailDTO::getProjectId).collect(Collectors.toList()));
                        }
                    }
                }
            }
            if (null != operateLog.getProjectId()) {
                Project project = projectService.findById(operateLog.getProjectId());
                operateLog.setProjectName(String.valueOf(project.getName()));
                if (null == operateLog.getEnterpriseId()) {
                    operateLog.setEnterpriseId(project.getEnterpriseId());
                }
                if (null == operateLog.getIndustryId()) {
                    operateLog.setIndustryId(project.getIndustryId());
                }
            }
            logTemplate.addOperateLog(operateLog);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("新增操作日志失败,errorMsg={}", e.getMessage());
            return ResultJson.fail("新增操作日志失败");
        }

        return ResultJson.success("新增操作日志成功");
    }

    @Override
    public void exportLog(HttpServletResponse response, LogQuery logQuery, EsPage pageList) throws IOException {
        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        if (LogTypeEnum.OPERATE_LOG.getType() == logQuery.getLogType()) {
            List<OperateLog> operateLogList = pageList.getRecords();
            String fileName = "操作日志_" + time + ".xlsx";
            AtomicInteger index = new AtomicInteger(1);
            SimpleDateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            List<OperateLogVO> list = operateLogList.stream().map(item -> {
                OperateLogVO operateLogVO = new OperateLogVO();
                BeanUtils.copyProperties(item, operateLogVO);
                operateLogVO.setIndex(index.getAndIncrement());
                if (!ObjectUtils.isEmpty(item.getCreatedAt())) {
                    operateLogVO.setCreatedAt(df.format(item.getCreatedAt()));
                }
                if (item.getResult() == 1) {
                    operateLogVO.setResult("成功");
                } else {
                    operateLogVO.setResult("失败");
                }
                if (!ObjectUtils.isEmpty(item.getOperateType())) {
                    operateLogVO.setOperateType(OperationTypeEnum.getDescriptionByType(item.getOperateType()));
                }
                return operateLogVO;
            }).collect(Collectors.toList());
            excelExportUtils.exportExcelStream(list, OperateLogVO.class, null, "Sheet1",  fileName, response);
        } else if (LogTypeEnum.LOGIN_LOG.getType() == logQuery.getLogType()) {
            List<LoginLog> loginLogList = pageList.getRecords();
            AtomicInteger index = new AtomicInteger(1);
            String fileName = "登录日志_" + time + ".xlsx";
            Short sourceClient = logQuery.getSourceClient();
            SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            if (sourceClient == SourceClientEnum.PLATFORM.getType()) {
                List<LoginLogPlatformVO> list = loginLogList.stream().map(item -> {
                    LoginLogPlatformVO loginLogVO = new LoginLogPlatformVO();
                    BeanUtils.copyProperties(item, loginLogVO);
                    loginLogVO.setIndex(index.getAndIncrement());
                    if (!ObjectUtils.isEmpty(item.getCreatedAt())) {
                        loginLogVO.setCreatedAt(df.format(item.getCreatedAt()));
                    }
                    if (org.springframework.util.StringUtils.isEmpty(item.getLoginAddress())) {
                        loginLogVO.setLoginAddress("/");
                    }
                    return loginLogVO;
                }).collect(Collectors.toList());
                excelExportUtils.exportExcelStream(list, LoginLogPlatformVO.class, null, "平台端",  fileName, response);
            } else if (sourceClient == SourceClientEnum.MOBILE.getType()) {
                List<LoginLogMobileVO> list = loginLogList.stream().map(item -> {
                    LoginLogMobileVO loginLogVO = new LoginLogMobileVO();
                    BeanUtils.copyProperties(item, loginLogVO);
                    loginLogVO.setIndex(index.getAndIncrement());
                    if (!ObjectUtils.isEmpty(item.getCreatedAt())) {
                        loginLogVO.setCreatedAt(df.format(item.getCreatedAt()));
                    }
                    if (org.springframework.util.StringUtils.isEmpty(item.getLoginAddress())) {
                        loginLogVO.setLoginAddress("/");
                    }
                    if (org.springframework.util.StringUtils.isEmpty(item.getVersion())) {
                        loginLogVO.setVersion("/");
                    }
                    return loginLogVO;
                }).collect(Collectors.toList());
                excelExportUtils.exportExcelStream(list, LoginLogMobileVO.class, null, "移动端",  fileName, response);
            }
        }
    }

    @Override
    public EsPage pageLoginLog(String appId, Short industryId, Integer envId, LogQuery query) {
        //日志类型
        query.setLogType(LogTypeEnum.LOGIN_LOG.getType());
        //索引
        query.setIndex(LogTypeEnum.LOGIN_LOG.getIndex());
        SearchSourceBuilder searchSource = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //应用
        IAppService appService = SpringContextUtils.getBean(IAppService.class);
        App app = appService.getByAppId(appId);
        if (null == app) {
            throw new DataException("应用不存在");
        }
        boolQuery.must(QueryBuilders.termQuery("appName.keyword", app.getName()));
        //业态
        boolQuery.must(QueryBuilders.termQuery("industryId", industryId));
        //运行环境
        boolQuery.must(QueryBuilders.termQuery("envId", envId));
        //检索条件
        //关键词
        loginNameNameIpOrSearch(query, boolQuery);
        //时间范围
        if (null != query.getValidityDateStart() && null != query.getValidityDateEnd()) {
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(query.getValidityDateEnd());
            calendar.add(Calendar.HOUR,23);
            calendar.add(Calendar.MINUTE,59);
            calendar.add(Calendar.SECOND,59);
            boolQuery.must(QueryBuilders
                    //传入时间
                    .rangeQuery("createdAt")
                    .from(query.getValidityDateStart().getTime())
                    .to(calendar.getTime().getTime()));
        }
        //排序
        query.setSortType("descend");
        setSearchSort(query, searchSource);
        searchSource.query(boolQuery);
        searchSource.sort("createdAt", SortOrder.DESC);
        searchSource.from((query.getCurrent() - 1) * query.getSize());
        searchSource.size(query.getSize());
        searchSource.timeout(TimeValue.timeValueSeconds(5));
        query.setSearchSourceBuilder(searchSource);
        try {
            return logTemplate.search(query);
        } catch (Exception e) {
            log.error("登录日志分页异常:{}", e.getMessage());
            throw new ApplicationException("登录日志分页异常");
        }
    }

    /**
     * 操作日志动态查询
     *
     * @param logQuery
     * @return
     */
    public EsPage getOperateLog(LogQuery logQuery) {

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();

        //boolBuilder 组合搜索条件
        //业态id搜索  IndustryEnum
        industrySearch(logQuery, boolBuilder);
        //精准查找 模块 (可多个)
        menusSearch(boolBuilder, logQuery);
        //精准查找  企业
        entsSearch(boolBuilder, logQuery);
        //精准查找  项目
        projectsSearch(boolBuilder, logQuery);
        //精准查找  操作类型
        operateTypesSearch(boolBuilder, logQuery);
        //时间范围内查找
        createdAtSearch(boolBuilder, logQuery);
        //模糊搜索 ip
        ipSearch(logQuery, boolBuilder);
        //模糊查找 用户名 or 姓名
        loginNameNameOrSearch(logQuery, boolBuilder);

        //sourceBuilder 设置额外的搜索配置

        //设置查询，可以是任何类型的QueryBuilder。
        sourceBuilder.query(boolBuilder);
        //设置搜索超时时间
        setSearchTime(logQuery, sourceBuilder);
        //设置搜索分页参数
        setSearchPage(logQuery, sourceBuilder);
        //设置搜索字段&过滤字段
        setSearchSelectColumns(logQuery, sourceBuilder);
        //设置排序
        setSearchSort(logQuery, sourceBuilder);
        logQuery.setSearchSourceBuilder(sourceBuilder);
        EsPage esPage = new EsPage();
        try {
            esPage = logTemplate.search(logQuery);
            log.info("sql:"+sourceBuilder.toString());
            return esPage;
        } catch (Exception e) {
            log.info("搜索操作日志失败，原因={}", e.getMessage());
            return esPage;
        }
    }

    private void entsSearch(BoolQueryBuilder boolBuilder, LogQuery logQuery) {
        if (!CollectionUtils.isEmpty(logQuery.getEntIds())){
            BoolQueryBuilder inBuilder = QueryBuilders.boolQuery();
            for (Integer entId : logQuery.getEntIds()){
                if (enterpriseService.isOperator(entId)){
                    ProjectQuery projectQuery = new ProjectQuery();
                    projectQuery.setEnterpriseId(entId);
                    List<Project> projects = projectService.list(projectQuery,null);
                    for (Project project : projects){
                        inBuilder.should(QueryBuilders.matchQuery("projectIds", project.getId()));
                    }
                }
            }
            List<Integer> entIds = logQuery.getEntIds();
            for (Integer entId : entIds) {
                inBuilder.should(QueryBuilders.matchQuery("enterpriseIds", entId));
            }
            boolBuilder.must(inBuilder);
        }
    }


    /**
     * 登录日志动态查询 （web端、app端）
     *
     * @param logQuery
     * @return
     */
    public EsPage getLoginLog(LogQuery logQuery) {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();

        //boolBuilder 组合搜索条件

        //登录日志分为 1： web端   2：移动端
        sourceClientSearch(logQuery, boolBuilder);

        //业态id搜索  IndustryEnum
        industrySearch(logQuery, boolBuilder);

        //模糊查找 用户名 or 姓名 or ip
        loginNameNameIpOrSearch(logQuery, boolBuilder);
        //时间范围内查找
        createdAtSearch(boolBuilder, logQuery);
        //精准查找  企业
        entsSearch(boolBuilder, logQuery);

        //app名称 来源搜索
        appNameSearch(boolBuilder, logQuery);

        //sourceBuilder 设置额外的搜索配置

        //设置查询，可以是任何类型的QueryBuilder。
        sourceBuilder.query(boolBuilder);
        //设置搜索超时时间
        setSearchTime(logQuery, sourceBuilder);
        //设置分页
        setSearchPage(logQuery, sourceBuilder);
        //设置搜索字段&过滤字段
        setSearchSelectColumns(logQuery, sourceBuilder);
        //设置排序
        setSearchSort(logQuery, sourceBuilder);
        logQuery.setSearchSourceBuilder(sourceBuilder);
        EsPage esPage = new EsPage();
        try {
            esPage = logTemplate.search(logQuery);
            return esPage;
        } catch (Exception e) {
            log.info("搜索登录日志失败，原因={}", e.getMessage());
            return esPage;
        }
    }


    /**
     * 业态id搜索   IndustryEnum
     *
     * @param logQuery
     * @param boolBuilder
     */
    public void industrySearch(LogQuery logQuery, BoolQueryBuilder boolBuilder) {
        if (null != logQuery.getIndustryId()) {
            MatchQueryBuilder industryMatchQuery = QueryBuilders.matchQuery("industryId", logQuery.getIndustryId());
            boolBuilder.must(industryMatchQuery);
        }
    }


    /**
     * 登录日志端的区分搜索 ，1： web端   2：移动端
     *
     * @param logQuery
     * @param boolBuilder
     */
    public void sourceClientSearch(LogQuery logQuery, BoolQueryBuilder boolBuilder) {
        if (null != logQuery.getSourceClient()) {
            MatchQueryBuilder sourceMatchQuery = QueryBuilders.matchQuery("sourceClient", logQuery.getSourceClient());
            boolBuilder.must(sourceMatchQuery);
        }
    }

    /**
     * 模糊查找 用户名 or 姓名 or ip
     *
     * @param logQuery
     * @param boolBuilder
     */
    public void loginNameNameIpOrSearch(LogQuery logQuery, BoolQueryBuilder boolBuilder) {
        //模糊查找 用户名 or 姓名 or ip
        if (StringUtils.isNotEmpty(logQuery.getKeyword())) {
            //多值组合查找，默认text分词模糊搜索，为了避免分词，指定type为keyword使用
            //使用通配符 左右通配  完全实现与sql一样效果， 但是左通配其实会影响查询效率，就和 like 使用%like一样也是会影响效率的
            QueryBuilder nameQueryBuilder = QueryBuilders.wildcardQuery("name.keyword", ("*" + logQuery.getKeyword() + "*"));
            QueryBuilder ipQueryBuilder = QueryBuilders.wildcardQuery("ip", ("*" + logQuery.getKeyword() + "*").toLowerCase());
            QueryBuilder loginNameQueryBuilder = QueryBuilders.wildcardQuery("loginName.keyword", ("*" + logQuery.getKeyword() + "*"));
            BoolQueryBuilder inBuilder = QueryBuilders.boolQuery();
            inBuilder.should(ipQueryBuilder).should(nameQueryBuilder).should(loginNameQueryBuilder);
            boolBuilder.must(inBuilder);
        }
    }


    /**
     * app名称 来源 搜索 ，支持多选
     *
     * @param boolBuilder
     * @param logQuery
     */
    private void appNameSearch(BoolQueryBuilder boolBuilder, LogQuery logQuery) {
        if (!CollectionUtils.isEmpty(logQuery.getAppNames())) {
            //多值in匹对
            BoolQueryBuilder inBuilder = QueryBuilders.boolQuery();
            List<String> appNames = logQuery.getAppNames();
            for (String appName : appNames) {
                inBuilder.should(QueryBuilders.matchQuery("appName.keyword", appName));
            }
            boolBuilder.must(inBuilder);
        }
    }

    /**
     * 功能模块名称 搜索，支持多选
     *
     * @param boolBuilder
     * @param logQuery
     */
    private void menusSearch(BoolQueryBuilder boolBuilder, LogQuery logQuery) {
        if (!CollectionUtils.isEmpty(logQuery.getMenus())) {
            //多值in匹对
            BoolQueryBuilder inBuilder = QueryBuilders.boolQuery();
            List<String> menus = logQuery.getMenus();
            for (String menu : menus) {
                inBuilder.should(QueryBuilders.matchQuery("menu.keyword", menu));
            }
            boolBuilder.must(inBuilder);
        }
    }

    /**
     * 项目id搜索，支持多选
     *
     * @param boolBuilder
     * @param logQuery
     */
    private void projectsSearch(BoolQueryBuilder boolBuilder, LogQuery logQuery) {
        if (!CollectionUtils.isEmpty(logQuery.getProjectIds())) {
            //单值匹对
            //   MatchQueryBuilder projectMatchQuery = QueryBuilders.matchQuery("projectId", logQuery.getProjectId());
            //多值in匹对
            BoolQueryBuilder inBuilder = QueryBuilders.boolQuery();
            List<Integer> projectIds = logQuery.getProjectIds();
            for (Integer projectId : projectIds) {
                inBuilder.should(QueryBuilders.matchQuery("projectId", projectId));
            }
            boolBuilder.must(inBuilder);
        }
    }

    /**
     * 操作类型搜索，支持多选
     *
     * @param boolBuilder
     * @param logQuery
     */
    private void operateTypesSearch(BoolQueryBuilder boolBuilder, LogQuery logQuery) {
        if (!CollectionUtils.isEmpty(logQuery.getOperateTypes())) {
            //多值in匹对
            BoolQueryBuilder inBuilder = QueryBuilders.boolQuery();
            List<Short> operateTypes = logQuery.getOperateTypes();
            for (Short type : operateTypes) {
                inBuilder.should(QueryBuilders.matchQuery("operateType", type));
            }
            boolBuilder.must(inBuilder);
        }
    }

    /**
     * 时间范围搜索
     *
     * @param boolBuilder
     * @param logQuery
     */
    private void createdAtSearch(BoolQueryBuilder boolBuilder, LogQuery logQuery) {
        if (null != logQuery.getValidityDateStart() && null != logQuery.getValidityDateEnd()) {
            //设置范围查询
            Long startTime = logQuery.getValidityDateStart().getTime();
            Long endTime = logQuery.getValidityDateEnd().getTime();
            RangeQueryBuilder rangequerybuilder = QueryBuilders
                    //传入时间
                    .rangeQuery("createdAt")
                    .from(startTime)
                    .to(endTime);

            boolBuilder.must(rangequerybuilder);
        }
    }

    /**
     * ip模糊搜索
     *
     * @param logQuery
     * @param boolBuilder
     */
    public void ipSearch(LogQuery logQuery, BoolQueryBuilder boolBuilder) {
        if (StringUtils.isNotEmpty(logQuery.getIp())) {
            //模糊搜索 ，避免纯数字精准查找，使用正则实现左右模糊搜索
            QueryBuilder ipQueryBuilder = QueryBuilders.wildcardQuery("ip", ("*" + logQuery.getIp() + "*").toLowerCase());
            boolBuilder.must(ipQueryBuilder);
        }
    }

    /**
     * 登录名&姓名 模糊搜索
     *
     * @param logQuery
     * @param boolBuilder
     */
    public void loginNameNameOrSearch(LogQuery logQuery, BoolQueryBuilder boolBuilder) {
        if (StringUtils.isNotEmpty(logQuery.getKeyword())) {

            //多值组合查找，默认text分词模糊搜索，为了避免分词，指定type为keyword使用
            //使用通配符 左右通配  完全实现与sql一样效果， 但是左通配其实会影响查询效率，就和 like 使用%like一样也是会影响效率的
            QueryBuilder nameQueryBuilder = QueryBuilders.wildcardQuery("name.keyword", ("*" + logQuery.getKeyword() + "*"));
            QueryBuilder loginNameQueryBuilder = QueryBuilders.wildcardQuery("loginName.keyword", ("*" + logQuery.getKeyword() + "*"));
            BoolQueryBuilder inBuilder = QueryBuilders.boolQuery();
            inBuilder.should(nameQueryBuilder).should(loginNameQueryBuilder);
            boolBuilder.must(inBuilder);
        }
    }

    /**
     * 设置控制允许搜索的时间
     *
     * @param logQuery
     * @param sourceBuilder
     */
    public void setSearchTime(LogQuery logQuery, SearchSourceBuilder sourceBuilder) {
        Integer searchTime = logQuery.getSearchTime();
        if (null == searchTime) {
            searchTime = 30;
        }
        //设置一个可选的超时，控制允许搜索的时间。
        sourceBuilder.timeout(new TimeValue(searchTime, TimeUnit.SECONDS));
    }

    /**
     * 设置搜索字段
     *
     * @param logQuery
     * @param sourceBuilder
     */
    public void setSearchSelectColumns(LogQuery logQuery, SearchSourceBuilder sourceBuilder) {
        // 第一个是获取字段，第二个是过滤的字段，默认获取全部
        if (null != logQuery.getSelectColumns() && 0 != logQuery.getSelectColumns().length) {
            if (null == logQuery.getNoSelectColumns() || 0 == logQuery.getNoSelectColumns().length) {
                sourceBuilder.fetchSource(logQuery.getSelectColumns(), new String[]{});
            } else {
                sourceBuilder.fetchSource(logQuery.getSelectColumns(), logQuery.getNoSelectColumns());
            }
        }
    }

    /**
     * 设置分页条件
     *
     * @param logQuery
     * @param sourceBuilder
     */
    public void setSearchPage(LogQuery logQuery, SearchSourceBuilder sourceBuilder) {
        //分页设置
        int size = logQuery.getSize();
        //设置确定结果要从哪个索引开始搜索的from选项，默认为0  ,当前页初始是1，所以需要减1
        Integer viewCurrent = logQuery.getCurrent();
        int current = viewCurrent - 1;
        current = current <= 0 ? 0 : current * size;
        sourceBuilder.from(current);
        sourceBuilder.size(size);
    }

    /**
     * 设置排序,正序、倒序
     *
     * @param logQuery
     * @param sourceBuilder
     */
    public void setSearchSort(LogQuery logQuery, SearchSourceBuilder sourceBuilder) {
        if (StringUtils.isNotEmpty(logQuery.getSortColumn()) && StringUtils.isNotEmpty(logQuery.getSortType())) {
            if (logQuery.getSortType().equals("ascend")) {
                sourceBuilder.sort(logQuery.getSortColumn(), SortOrder.ASC);
            } else if (logQuery.getSortType().equals("descend")) {
                sourceBuilder.sort(logQuery.getSortColumn(), SortOrder.DESC);
            }
        } else {
            //默认倒序，根据生成时间
            sourceBuilder.sort("createdAt", SortOrder.DESC);
        }
    }

}
